﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Quark.Framework.Threading;

namespace Quark.Profiler.Framework
{
    /// <summary>
    /// 性能计数
    /// </summary>
    [Serializable()]
    public abstract class ProfilingCounter
    {
        #region Members

        private long _beginTicks;
        private long _endTicks;
        private AtomicBool _succeed;

        #endregion

        #region Constructors

        public ProfilingCounter()
        {
            this._succeed = new AtomicBool(false);
        }

        #endregion

        #region Properties

        /// <summary>
        /// 获取或设置开始执行的毫秒刻度
        /// </summary>
        public int BeginTicks
        {
            get { return (int)Interlocked.Read(ref _beginTicks); }
            set { Interlocked.Exchange(ref _beginTicks, value); }
        }
        /// <summary>
        /// 获取或设置结束执行时的毫秒刻度
        /// </summary>
        public int EndTicks
        {
            get { return (int)Interlocked.Read(ref _endTicks); }
            set { Interlocked.Exchange(ref _endTicks, value); }
        }
        /// <summary>
        /// 获取当前执行一共花费的毫秒数
        /// </summary>
        public int ElapsedTicks
        {
            get { return Math.Abs(this.EndTicks - this.BeginTicks); }
        }
        /// <summary>
        /// 获取当前执行是否成功
        /// </summary>
        public bool Succeed
        {
            get { return this._succeed.Value; }
            set { this._succeed.Value = value; }
        }

        #endregion
    }

    /// <summary>
    /// 针对测试活动的性能计数
    /// </summary>
    [Serializable()]
    public class ProfilingTestActivityCounter : ProfilingCounter
    {
        #region Constructors

        protected ProfilingTestActivityCounter()
            : base()
        {
        }

        public ProfilingTestActivityCounter(IProfilingActivity activity)
            : base()
        {
        }

        #endregion
    }

    /// <summary>
    /// 针对测试用例的性能计数
    /// </summary>
    [Serializable()]
    public class ProfilingTestCaseCounter : ProfilingCounter
    {
        #region Members

        private string _testCaseId;
        private string _testCaseTitle;
        private DateTime _beginTime;
        private DateTime _endTime;
        private ProfilingTestActivityCounter[] _activityCounters;

        #endregion

        #region Constructors

        protected ProfilingTestCaseCounter()
            : base()
        {
        }

        public ProfilingTestCaseCounter(ProfilingTestCase testCase)
            : base()
        {
            this._testCaseId = testCase.Id;
            this._testCaseTitle = testCase.Title;
            IProfilingActivity[] activities = testCase.ProfilingActivityInstances;
            this._activityCounters = new ProfilingTestActivityCounter[activities.Length];
            for (int i = 0; i < activities.Length; i++)
            {
                this._activityCounters[i] = new ProfilingTestActivityCounter(activities[i]);
            }
        }

        #endregion

        #region Properties

        /// <summary>
        /// 获取测试用例ID
        /// </summary>
        public string TestCaseId
        {
            get { return this._testCaseId; }
        }

        /// <summary>
        /// 获取测试用例标题
        /// </summary>
        public string TestCaseTitle
        {
            get { return this._testCaseTitle; }
        }

        /// <summary>
        /// 获取或设置开始执行的起始时间
        /// </summary>
        public DateTime BeginTime
        {
            get { return this._beginTime; }
            set { this._beginTime = value; }
        }

        /// <summary>
        /// 获取或设置执行完成的时间
        /// </summary>
        public DateTime EndTime
        {
            get { return this._endTime; }
            set { this._endTime = value; }
        }

        /// <summary>
        /// 获取指定索引对应的测试活动性能计数
        /// </summary>
        /// <param name="index">索引</param>
        /// <returns>索引对应的测试活动性能计数</returns>
        public ProfilingTestActivityCounter this[int index]
        {
            get
            {
                return this._activityCounters[index];
            }
        }

        #endregion
    }

    /// <summary>
    /// 针对测试项目的性能计数
    /// </summary>
    [Serializable()]
    public class ProfilingTestProjectCounter : ProfilingCounter
    {
        #region Members

        private string _testProjectId;
        private string _testProjectTitle;
        private ProfilingTestCaseCounter[] _caseCounters;

        #endregion

        #region Constructors

        protected ProfilingTestProjectCounter()
            : base()
        {
        }

        public ProfilingTestProjectCounter(ProfilingTestProject project)
            : base()
        {
            this._testProjectId = project.Id;
            this._testProjectTitle = project.Title;
            ProfilingTestCase[] testCases = project.Cases;
            this._caseCounters = new ProfilingTestCaseCounter[testCases.Length];
            for (int i = 0; i < testCases.Length; i++)
            {
                this._caseCounters[i] = new ProfilingTestCaseCounter(testCases[i]);
            }
        }

        #endregion

        #region Properties

        /// <summary>
        /// 获取测试项目的ID
        /// </summary>
        public string TestProjectId
        {
            get { return this._testProjectId; }
        }

        /// <summary>
        /// 获取测试项目的标题
        /// </summary>
        public string TestProjectTitle
        {
            get { return this._testProjectTitle; }
        }

        /// <summary>
        /// 获取指定索引对应的测试用例性能计数
        /// </summary>
        /// <param name="index">索引</param>
        /// <returns>索引对应的测试用例性能计数</returns>
        public ProfilingTestCaseCounter this[int index]
        {
            get
            {
                return this._caseCounters[index];
            }
        }

        #endregion
    }
}
